/* ======================================================================================== *\

		FILE:				PipeLayout.h
		AUTHOR:				Jack Hoxley

		DESCRIPTION:		A layout represents the graph of possible moves by any given
							pipe. Due to there being multiple pipes at any one time it is
							necessary to have a central manager/layout that ensures they
							don't overlap or otherwise screw each other over.

		CHANGE:				5th May 2007
								Basic public interface defined.
							14th July 2007
								Added iteration counting variable
								Added mechanism for clients to query last change for a pipe

\* ======================================================================================== */

#ifndef INC_PIPELAYOUT_H
#define INC_PIPELAYOUT_H

#include "Pipe.h"

namespace PipeSim
{
	class PipeLayout
	{
		public:
			PipeLayout( );
			PipeLayout( const UINT16& nPipes );
			PipeLayout( const UINT16& xSize, const UINT16& ySize, const UINT16& zSize, const UINT16& nPipes );

			~PipeLayout( );

			void IterateSimulation( );

			void ResetSimulation( );

			UINT16 LayoutXDimension( ) const;
			UINT16 LayoutYDimension( ) const;
			UINT16 LayoutZDimension( ) const;

			UINT16 NumberOfPipes( ) const;

			UINT32 IterationOfLastChange( const UINT16& pipe ) const;

			void GetPipeCoordinates( const UINT16& pipe, Utils::CoordinateList* pOut ) const;

			UINT32 PipeLength( const UINT16& pipe ) const;

		private:
			// No real need for a copy ctor for now
			PipeLayout( const PipeLayout& );

			// The actual pipes:
			UINT16		m_PipeCount;
			Pipe**		m_ppPipes;

			// Cube layout implies a 3D array:
			UINT16		m_XSize;
			UINT16		m_YSize;
			UINT16		m_ZSize;
			bool***		m_pppState;

			bool		m_SimulationReady;
			UINT32		m_IterationCount;

			// To make things a little safer, have an
			// accessor function into the state to check
			// for NULL's:
			bool CheckState( const UINT16& x, const UINT16& y, const UINT16& z );

			void CreateLayout( const UINT16& xSize, const UINT16& ySize, const UINT16& zSize, const UINT16& nPipes );
			void CreatePipes( );
	};
}

#endif